using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


using System.IO.Ports;

using System.Threading;

using System.IO;

using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;


using System.Drawing.Drawing2D;

namespace YangtzeFilterTestSystem
{
    public partial class PanasonicDriverForm : Form
    {

        private static SerialPort port1;
        private static SerialPort port2;

        private System.Timers.Timer myTimer;

        private System.Timers.Timer OPCDataAcquireTimer;

        Thread Motor1JogThread;
        Thread Motor2JogThread;
        Thread ScanningThread;

        public int CurrentX, CurrentY;

        Graphics graphicsObject;

        Point RealTimeLocation;

        private byte ScanningDirection;

        
        Bitmap b;
        Graphics dc;

        public PanasonicDriverForm()
        {
            InitializeComponent();

            myTimer = new System.Timers.Timer();

            myTimer.AutoReset = true;
            myTimer.Interval = 1000;
            myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
            myTimer.Enabled = false;

            OPCDataAcquireTimer = new System.Timers.Timer();
            OPCDataAcquireTimer.AutoReset = true;
            OPCDataAcquireTimer.Interval = 1000;
            OPCDataAcquireTimer.Elapsed += new System.Timers.ElapsedEventHandler(OPCDataAcquireTimer_Elapsed);
            //OPCDataAcquireTimer.Enabled = true;

            //OPCDataAcquireTimer.Enabled = true;
            
            /*
            Dev.DownstreamOPC.Location = 0;
            Dev.DownstreamOPC.InitialDelay = 0;
            Dev.DownstreamOPC.HoldTime = 0;
            Dev.DownstreamOPC.SampleTime = 1;
             */


            MDriverControlEnableCBox.SelectedIndex = 1;

            this.MDriverControlEnableCBox.SelectedIndexChanged += new EventHandler(MDriverControlEnableCBox_SelectedIndexChanged);

            graphicsObject = Graphics.FromHwnd(this.Handle);

            RealTimeLocation = new Point(150, 550);

            ScanningDirection = Constant.FOREWARD;

            b = new Bitmap(this.Width, this.Height);
            dc = Graphics.FromImage((System.Drawing.Image)b);

            port1 = new SerialPort();
            port1.PortName = "COM1";
            port1.BaudRate = 38400;
            port1.DataBits = 8;
            port1.Parity = Parity.Even;
            port1.StopBits = StopBits.One;
            port1.WriteTimeout = 2000;
            port1.ReadTimeout = 2000;

            //port1.Open();
        }

        public void myTimer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
        {
            Dev.MDriverX.EquipmentStatusReading();

            StatusLbl.Text = Dev.MDriverX.ResponsedStatus + "\n" + Dev.MDriverX.D_STATUS1.ToString() + "\n" + Dev.MDriverX.ResponsedD_STATUS1 + "\n" + Dev.MDriverX.D_STATUS1.ToString() + "\n" + Dev.MDriverX.ResponsedD_STATUS2;
        }

        public void OPCDataAcquireTimer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
        {
            

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            base.OnPaint(e);
        }



        private void SendToDriver1Btn_Click(object sender, EventArgs e)
        {
            string str = InputRTBox.Text;

            char[] charSeparators = new char[] { ',',' ',';' };
            string[] numbersString = str.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

            int NumberOfBytes = numbersString.Length;
            byte[] sendBytes = new byte[NumberOfBytes + 1];
            int cnt = 0;

            byte checksum = 0x00;
            byte tmp;

            foreach (string num in numbersString)
            {
                tmp = Convert.ToByte(num, 16);
                sendBytes[cnt++] = tmp;
                checksum += tmp;
            }


            sendBytes[cnt] = checksum;

            ChecksumTBox.Text = checksum.ToString("X");


            port1.Write(sendBytes, 0, NumberOfBytes + 1);
            Thread.Sleep(200);

            int NumberOfReturnBytes;
            NumberOfReturnBytes = port1.ReadByte();
            Thread.Sleep(200);

            byte[] receiveBytes = new byte[NumberOfReturnBytes];

            receiveBytes[0] = Convert.ToByte(NumberOfReturnBytes);
            port1.Read(receiveBytes, 1, NumberOfReturnBytes - 1);

            string ReceivedString = "";

            for (int i = 0; i < NumberOfReturnBytes; i++)
            {
                ReceivedString += receiveBytes[i].ToString("X2") + " ";
            }

            OutputRTBox.Text = ReceivedString;
         }

        private void InstantStopBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverX.InstantaneousStop();
            Motor1JogThread.Abort();

        }

        private void ServoONOFFBtn_Click(object sender, EventArgs e)
        {
            try
            {

                if (ServoONOFFBtn.Text == "ServoON")
                {
                    if (!Dev.MDriverX.IsServoON)
                    {
                        Dev.MDriverX.ServoON();

                        ServoONOFFBtn.Text = "ServoOFF";
                    }
                    else
                    {
                        Dev.MDriverX.ServoOFF();
                    }
                }
                else if (ServoONOFFBtn.Text == "ServoOFF")
                {
                    if (Dev.MDriverX.IsServoON)
                    {
                        Dev.MDriverX.ServoOFF();

                        ServoONOFFBtn.Text = "ServoON";
                    }
                }
                 
            }
            catch (System.Exception ex)
            {
                //GlobalVariables.log.Error("COM6 is not Opened!" + ex.ToString());
                MessageBox.Show("Error" + ex.ToString());
            }
            
        }

        private void Motro1JogBtn_Click(object sender, EventArgs e)
        {
            Motor1JogThread = new Thread(Motor1Jog);
            Motor1JogThread.Start();
        }

        private void Motor1Jog()
        {
            Dev.MDriverX.AccelerationSetting();
            Dev.MDriverX.DecelerationSetting();

            for (; ; )
            {
                Dev.MDriverX.JogC(200, Constant.DIR_CW);
                Thread.Sleep(30000);

                Dev.MDriverX.InstantaneousStop();

                Dev.MDriverX.JogC(200, Constant.DIR_CCW);
                Thread.Sleep(30000);

                Dev.MDriverX.InstantaneousStop();

                /*

                port1.Write(new byte[] { 0x0A, 0x00, 0x11, 0x03, 0x01, 0x00, 0x80, 0x00, 0x00, 0x9F }, 0, 10);
                Thread.Sleep(30000);

                port1.Write(new byte[] { 0x04, 0x00, 0x15, 0x19 }, 0, 4);
                Thread.Sleep(300);

                port1.Write(new byte[] { 0x0A, 0x00, 0x11, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00, 0x9E }, 0, 10);
                Thread.Sleep(30000);

                port1.Write(new byte[] { 0x04, 0x00, 0x15, 0x19 }, 0, 4);
                Thread.Sleep(300);
                 */
            }

        }

        private void Motor2InstantStopBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverY.InstantaneousStop();
            Motor2JogThread.Abort();
        }

        private void Motor2JogBtn_Click(object sender, EventArgs e)
        {
            Motor2JogThread = new Thread(Motor2Jog);
            Motor2JogThread.Start();
        }

        private void Motor2Jog()
        {
            Dev.MDriverY.AccelerationSetting();
            Dev.MDriverY.DecelerationSetting();

            for (; ; )
            {
                Dev.MDriverY.JogC(200, Constant.DIR_CW);
                Thread.Sleep(30000);

                Dev.MDriverY.InstantaneousStop();

                Dev.MDriverY.JogC(200, Constant.DIR_CCW);
                Thread.Sleep(30000);

                Dev.MDriverY.InstantaneousStop();

            }
        }

        private void ServoONOFFBtn2_Click(object sender, EventArgs e)
        {
            if (ServoONOFFBtn2.Text == "ServoON")
            {
                if (!Dev.MDriverY.IsServoON)
                {
                    Dev.MDriverY.ServoON();

                    ServoONOFFBtn2.Text = "ServoOFF";
                }
                else
                {
                    Dev.MDriverY.ServoOFF();
                }
            }
            else if (ServoONOFFBtn2.Text == "ServoOFF")
            {
                if (Dev.MDriverY.IsServoON)
                {
                    Dev.MDriverY.ServoOFF();

                    ServoONOFFBtn2.Text = "ServoON";
                }
            }
        }

        private void SendToDriver2Btn_Click(object sender, EventArgs e)
        {
           string str = InputRTBox.Text;

            char[] charSeparators = new char[] { ',',' ',';' };
            string[] numbersString = str.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);

            int NumberOfBytes = numbersString.Length;
            byte[] sendBytes = new byte[NumberOfBytes + 1];
            int cnt = 0;

            byte checksum = 0x00;
            byte tmp;

            foreach (string num in numbersString)
            {
                tmp = Convert.ToByte(num, 16);
                sendBytes[cnt++] = tmp;
                checksum += tmp;
            }


            sendBytes[cnt] = checksum;

            ChecksumTBox.Text = checksum.ToString("X");


            port2.Write(sendBytes, 0, NumberOfBytes + 1);
            Thread.Sleep(200);

            int NumberOfReturnBytes;
            NumberOfReturnBytes = port2.ReadByte();
            Thread.Sleep(200);

            byte[] receiveBytes = new byte[NumberOfReturnBytes];

            receiveBytes[0] = Convert.ToByte(NumberOfReturnBytes);
            port2.Read(receiveBytes, 1, NumberOfReturnBytes - 1);

            string ReceivedString = "";

            for (int i = 0; i < NumberOfReturnBytes; i++)
            {
                ReceivedString += receiveBytes[i].ToString("X2") + " ";
            }

            OutputRTBox.Text = ReceivedString;

        }


         private void TestStatusBtn_Click(object sender, EventArgs e)
        {
            Thread.Sleep(300);

            Dev.MDriverX.EquipmentStatusReading();

            MessageBox.Show(Dev.MDriverX.ResponsedStatus +"\n" + Dev.MDriverX.D_STATUS1.ToString() + "\n" + Dev.MDriverX.ResponsedD_STATUS1 + "\n" + Dev.MDriverX.D_STATUS1.ToString() + "\n" + Dev.MDriverX.ResponsedD_STATUS2);
        }

        private void Motor1CWBtn_Click(object sender, EventArgs e)
        {

            Dev.MDriverX.AccelerationSetting();
            Dev.MDriverX.DecelerationSetting();

            Dev.MDriverX.JogC(800, Constant.DIR_CW);
        }

        private void Motor1CCWBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverX.AccelerationSetting();
            Dev.MDriverX.DecelerationSetting();

            Dev.MDriverX.JogC(800, Constant.DIR_CCW);
        }


        private void MDriverControlEnableCBox_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (MDriverControlEnableCBox.SelectedIndex == 0)
            {
                PLC.MDriverControlEnable = false;
            }

            if (MDriverControlEnableCBox.SelectedIndex == 1)
            {
                PLC.MDriverControlEnable = true;
            }
        }

        private void Motor2CWBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverY.AccelerationSetting();
            Dev.MDriverY.DecelerationSetting();

            Dev.MDriverY.JogC(900, Constant.DIR_CW);
        }


        private void Motor2CCWBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverY.AccelerationSetting();
            Dev.MDriverY.DecelerationSetting();

            Dev.MDriverY.JogC(900, Constant.DIR_CCW);
        }

        private void Motor2StepBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverY.AccelerationSetting();
            Dev.MDriverY.DecelerationSetting();

            Dev.MDriverY.StepC(500000, 200, Constant.DIR123);
        }

        private void Motor1Step_Click(object sender, EventArgs e)
        {
            Dev.MDriverX.AccelerationSetting();
            Dev.MDriverX.DecelerationSetting();

            Dev.MDriverX.StepC(1000000, 200, Constant.DIR321);
        }

        private void TestBtn_Click(object sender, EventArgs e)
        {

            ScanningThread = new Thread(Scanning);
            ScanningThread.Start();

        }

        private void Scanning()
        {
            /*
            Scanner.Initialize();

            Scanner.MoveTo(10, 10);

            Dev.DownstreamOPC1.Location = 0;
            Dev.DownstreamOPC1.InitialDelay = 0;
            Dev.DownstreamOPC1.HoldTime = 0;
            Dev.DownstreamOPC1.SampleTime = 1;

            for (int i = 0; i < 5; i++)
            {


                Dev.DownstreamOPC1.InstrumentStart();
                OPCDataAcquireTimer.Enabled = true;

                Scanner.MoveX(1200, Constant.DIR321);

                OPCDataAcquireTimer.Enabled = false;
                Thread.Sleep(300);

                Dev.DownstreamOPC1.InstrumentStop();

                Scanner.MoveY(30, Constant.DIR321);
                //Thread.Sleep(3000);

                Dev.DownstreamOPC1.InstrumentStart();

                OPCDataAcquireTimer.Enabled = true;

                Scanner.MoveX(1200, Constant.DIR123);

                OPCDataAcquireTimer.Enabled = false;
                Thread.Sleep(300);

                Dev.DownstreamOPC1.InstrumentStop();

                Scanner.MoveY(30, Constant.DIR321);
                //Thread.Sleep(3000);

            }
             */

            /*
            // X: Step; Y: Scanning
            
            Dev.MDriverX.StepC(20000, 200, Constant.DIR321);
            Dev.MDriverY.StepC(50000, 200, Constant.DIR321);

            for (int i = 0; i < 13; i++)
            {
                Dev.MDriverX.StepC(33333, 200, Constant.DIR321);
                Dev.MDriverY.StepC(666666, 800, Constant.DIR321);
                Dev.MDriverX.StepC(33333, 200, Constant.DIR321);
                Dev.MDriverY.StepC(666666, 800, Constant.DIR123);
            }
             */
             

            /*
            
            // X: Scanning; Y: Step
            Dev.MDriverX.StepC(20000, 200, Constant.DIR321);
            Dev.MDriverY.StepC(20000, 200, Constant.DIR321);


            for (int i = 0; i < 10; i++)
            {
                Dev.MDriverX.StepC(1333333, 800, Constant.DIR321);
                Dev.MDriverY.StepC(33333, 500, Constant.DIR321);
                Dev.MDriverX.StepC(1333333, 800, Constant.DIR123);
                Dev.MDriverY.StepC(33333, 500, Constant.DIR321);
            }
             */
             


            /*
            // X: Step; Y: Step
            for (int i = 0; i < 10; i++)
            {
                int j;

                for (j = 0; j < 40; j++)
                {
                    Dev.MDriverX.StepC(33333, 500, Constant.DIR321);
                }

                Dev.MDriverY.StepC(33333, 500, Constant.DIR321);

                for (j = 0; j < 40; j++)
                {
                    Dev.MDriverX.StepC(33333, 500, Constant.DIR123);
                }
              
                Dev.MDriverY.StepC(33333, 500, Constant.DIR321);
            }
             */
             


        }

        private void HomeBtn_Click(object sender, EventArgs e)
        {
            Dev.MDriverX.AccelerationSetting();
            Dev.MDriverX.DecelerationSetting();

            Dev.MDriverY.AccelerationSetting();
            Dev.MDriverY.DecelerationSetting();

            Dev.MDriverX.JogC(500, Constant.DIR123);
            Dev.MDriverY.JogC(500, Constant.DIR123);
        }



        private void MoveToBtn_Click(object sender, EventArgs e)
        {
            Scanner.MoveTo(Convert.ToInt32(X_TBox.Text), Convert.ToInt32(Y_TBox.Text));
        }

        private void OPCStartBtn_Click(object sender, EventArgs e)
        {
            //Dev.DownstreamOPC1.InstrumentStart();

            dc.Clear(Color.White);

            OPCDataAcquireTimer.Enabled = true;

        }

        private void OPCStopBtn_Click(object sender, EventArgs e)
        {
            OPCDataAcquireTimer.Enabled = false;

            Thread.Sleep(500);

            Dev.DownstreamOPC1.InstrumentStop();
        }

        private void TwoDGraphicsBtn_Click(object sender, EventArgs e)
        {
            

            // ellipse rectangle and gradient brush
            Rectangle ColorReferenceRect = new Rectangle(150, 450, 1300, 50);
            LinearGradientBrush linearBrush =
                new LinearGradientBrush(ColorReferenceRect, Color.Blue,
                    Color.Yellow, LinearGradientMode.ForwardDiagonal);

            LinearGradientBrush linearBrushBlue2Red = new LinearGradientBrush(ColorReferenceRect, Color.Blue, Color.Red, LinearGradientMode.Horizontal);

            //LinearGradientBrush linearBrushBlue2Red = new LinearGradientBrush(
            // draw ellipse filled with a blue-yellow gradient
            //graphicsObject.FillEllipse(linearBrushBlue2Red, 5, 30, 650, 1000);

            Color[] colors = { Color.Blue, Color.Green, Color.Yellow, Color.Orange, Color.Red };
            float[] positions = { 0.0f, 0.3f, 0.5f, 0.7f, 1.0f };

            ColorBlend blend = new ColorBlend();
            blend.Colors = colors;
            blend.Positions = positions;



            linearBrushBlue2Red.InterpolationColors = blend;


            graphicsObject.FillRectangle(linearBrushBlue2Red, ColorReferenceRect);

            /*

            Rectangle FilterRect = new Rectangle(150, 550, 1300, 300);
            LinearGradientBrush BlueBrush = new LinearGradientBrush(FilterRect, Color.Blue, Color.Blue, LinearGradientMode.Horizontal);

            graphicsObject.FillRectangle(BlueBrush, FilterRect);
             */

        }

        private void PumpStartStopBtn_Click(object sender, EventArgs e)
        {
            if (PumpStartStopBtn.Text == "PumpStart")
            {
                PLC.Open(Constant.SSR_PUMP_DOWNSTREAM1);

                PumpStartStopBtn.Text = "PumpStop";
            }
            else if (PumpStartStopBtn.Text == "PumpStop")
            {
                PLC.Close(Constant.SSR_PUMP_DOWNSTREAM1);

                PumpStartStopBtn.Text = "PumpStart";
            }
        }

        private void TempBtn_Click(object sender, EventArgs e)
        {
            //MessageBox.Show(Dev.DownstreamOPC1.DeviceStatus);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            UpperLimitTBox.Text = (chisquaredistr.invchisquaredistribution((Convert.ToDouble(ParticleTBox.Text) + 1) * 2, 0.025) / 2).ToString();

            LowerLimitTBox.Text = (chisquaredistr.invchisquaredistribution(Convert.ToDouble(ParticleTBox.Text) * 2, 0.975) / 2).ToString();
        }
    }
}